package com.ibeeking.found.cop.b.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ibeeking.found.cop.b.rest.service.IMsgFansMomentTaskFriendsService;
import com.ibeeking.found.cop.b.rest.service.IMsgFansMomentTaskSenderService;
import com.ibeeking.found.cop.b.rest.service.IWxOpenService;
import com.ibeeking.found.cop.service.common.dos.MsgFansMomentTaskSenderDO;
import com.ibeeking.found.cop.service.common.query.MsgFansMomentTaskSenderQuery;
import com.ibeeking.found.cop.service.common.vo.MsgFansMomentTaskSenderVO;
import com.ibeeking.found.cop.service.mapper.MsgFansMomentTaskSenderMapper;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.json.JsonUtils;
import me.chanjar.weixin.cp.api.WxCpExternalContactService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.external.WxCpGetMomentCustomerList;
import me.chanjar.weixin.cp.bean.external.WxCpGetMomentTask;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName MsgFansMomentTaskSenderServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-01-27 18:50
 **/
@Service
public class MsgFansMomentTaskSenderServiceImpl extends ServiceImpl<MsgFansMomentTaskSenderMapper, MsgFansMomentTaskSenderDO> implements IMsgFansMomentTaskSenderService {

    @Resource
    private MsgFansMomentTaskSenderMapper msgFansMomentTaskSenderMapper;

    @Resource
    private IMsgFansMomentTaskFriendsService msgFansMomentTaskFriendsServiceImpl;

    @Resource
    private IWxOpenService wxOpenServiceImpl;

    @Override
    public List<MsgFansMomentTaskSenderVO> list(MsgFansMomentTaskSenderQuery query) {
        List<MsgFansMomentTaskSenderDO> entityDOS = msgFansMomentTaskSenderMapper.selectList(new LambdaQueryWrapper<MsgFansMomentTaskSenderDO>()
                .eq(query.getId() != null, MsgFansMomentTaskSenderDO::getId, query.getId())
                .eq(StringUtils.isNotBlank(query.getMomentCode()), MsgFansMomentTaskSenderDO::getMomentCode, query.getMomentCode())
                .eq(query.getMomentId() != null, MsgFansMomentTaskSenderDO::getMomentId, query.getMomentId())
        );
        List<MsgFansMomentTaskSenderVO> entityVOS =JsonUtils.jsonToList(entityDOS, MsgFansMomentTaskSenderVO.class);
        return entityVOS;
    }

    @Override
    public List<MsgFansMomentTaskSenderVO> queryByMomentCode(String momentCode) {
        MsgFansMomentTaskSenderQuery query = new MsgFansMomentTaskSenderQuery();
        query.setMomentCode(momentCode);
        return this.getBean().list(query);
    }

    @Override
    public MsgFansMomentTaskSenderVO queryById(Long id) {
        MsgFansMomentTaskSenderDO entityDO = msgFansMomentTaskSenderMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        MsgFansMomentTaskSenderVO entityVO = BeanUtil.convertBean(entityDO, MsgFansMomentTaskSenderVO.class);
        return entityVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean syncFansMomentTaskSenderListFromWxCp(Integer tenantId, List<String> momentCodeList){
        if(Collections3.isNotEmpty(momentCodeList)) {
            Map<String, List<String>> allValidSenderMap = new HashMap<>();

            WxCpService wxCpService = wxOpenServiceImpl.getWxCpService(tenantId.longValue());
            WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
            if (wxCpConfigStorage == null) {
                throw new BusinessException("获取企微服务失败!");
            }

            WxCpExternalContactService wxCpExternalContactService = wxCpService.getExternalContactService();
            if (wxCpExternalContactService == null) throw new BusinessException("获取企微服务外部联系人服务!");
            List<MsgFansMomentTaskSenderDO> allNeedUpdateMomentTaskSenderDOS = new ArrayList<>();

            for(String momentCode: momentCodeList) {
                String nextCursor = null;
                List<MsgFansMomentTaskSenderDO> momentTaskSenderDOS = msgFansMomentTaskSenderMapper.selectList(new LambdaQueryWrapper<MsgFansMomentTaskSenderDO>().eq(MsgFansMomentTaskSenderDO::getMomentCode, momentCode));
                Map<String, MsgFansMomentTaskSenderDO> momentTaskSenderMap = Collections3.isNotEmpty(momentTaskSenderDOS)?momentTaskSenderDOS.stream().collect(Collectors.toMap(MsgFansMomentTaskSenderDO::getSenderCode, x->x, (o, n) -> n)):null;
                List<String> allValidSenderList = new ArrayList<>();
                do {
                    try {
                        WxCpGetMomentTask wxCpGetMomentTask = wxCpExternalContactService.getMomentTask(momentCode, nextCursor, 800);
                        LogUtils.info("====process wxCpGetMomentTask:{}====", JsonUtils.toJsonStr(wxCpGetMomentTask));
                        if(wxCpGetMomentTask!=null){
                            nextCursor = wxCpGetMomentTask.getNextCursor();
                            List<WxCpGetMomentTask.MomentTaskItem> momentTaskItemList  = wxCpGetMomentTask.getTaskList();
                            if(Collections3.isNotEmpty(momentTaskItemList)){
                                for(WxCpGetMomentTask.MomentTaskItem momentTaskItem: momentTaskItemList){
                                   String employeeCode =  momentTaskItem.getUserId();
                                   String publishStatus = momentTaskItem.getPublishStatus();
                                   if(StringUtils.isNotEmpty(employeeCode)){
                                       allValidSenderList.add(employeeCode);
                                       if(momentTaskSenderMap!=null && momentTaskSenderMap.containsKey(employeeCode)) {
                                           MsgFansMomentTaskSenderDO msgFansMomentTaskSenderDO = momentTaskSenderMap.get(employeeCode);
                                           msgFansMomentTaskSenderDO.setPublishStatus(Integer.valueOf(publishStatus));

                                           List<Map<String, String>> visibleRangeList = new ArrayList<>();
                                           String nextVisibleRangeCursor = null;
                                           do {
                                               WxCpGetMomentCustomerList wxCpGetMomentCustomerList = wxCpExternalContactService.getMomentCustomerList(momentCode, employeeCode, nextVisibleRangeCursor, 800);
                                               if (wxCpGetMomentCustomerList != null) {
                                                   nextVisibleRangeCursor = wxCpGetMomentCustomerList.getNextCursor();
                                                   List<me.chanjar.weixin.cp.bean.external.moment.CustomerItem> customerItemList = wxCpGetMomentCustomerList.getCustomerList();
                                                   if (Collections3.isNotEmpty(customerItemList)) {

                                                       for (me.chanjar.weixin.cp.bean.external.moment.CustomerItem customerItem : customerItemList) {
                                                           Map<String, String> visibleRange = new HashMap<>();
                                                           visibleRange.put("employeeCode", customerItem.getUserId());
                                                           visibleRange.put("friendsCode", customerItem.getExternalUserId());
                                                           visibleRangeList.add(visibleRange);
                                                       }
                                                   }
                                               } else {
                                                   nextVisibleRangeCursor = null;
                                               }
                                           } while (nextVisibleRangeCursor == null);
                                           if (Collections3.isNotEmpty(visibleRangeList)) {
                                               msgFansMomentTaskSenderDO.setVisibleRange(JsonUtils.toJsonStr(visibleRangeList));
                                           }
                                           allNeedUpdateMomentTaskSenderDOS.add(msgFansMomentTaskSenderDO);
                                       }
                                   }
                                }
                            }
                        }else{
                            nextCursor = null;
                        }
                    } catch (Exception e) {
                        LogUtils.error("获取客户朋友圈企业发表的列表，失败原因{}", e);
                        return false;
                    }
                } while (nextCursor == null);
                if(Collections3.isNotEmpty(allValidSenderList)) {
                    allValidSenderMap.put(momentCode, allValidSenderList);
                }
            }
            LogUtils.info("====process momentCodeList:{}====", JsonUtils.toJsonStr(momentCodeList));
            if(Collections3.isNotEmpty(momentCodeList)){
                msgFansMomentTaskFriendsServiceImpl.syncFansMomentTaskFriendsListFromWxCp(tenantId,momentCodeList, allValidSenderMap);
            }
            LogUtils.info("====process allNeedUpdateMomentTaskSenderDOS:{}====", JsonUtils.toJsonStr(allNeedUpdateMomentTaskSenderDOS));
            if(Collections3.isNotEmpty(allNeedUpdateMomentTaskSenderDOS)){
                this.updateBatchById(allNeedUpdateMomentTaskSenderDOS);
            }
        }
        return false;
    }

    private IMsgFansMomentTaskSenderService getBean(){
        return SpringBeanUtil.getBean(MsgFansMomentTaskSenderServiceImpl.class);
    }
}
